<?php
namespace app\common\service\swoole;
use app\common\library\CommonFun;
use app\common\service\ElkLog;
use swoole_server;

/**
 * Created by PhpStorm.
 * User: 96151
 * Date: 2018/11/29
 * Time: 19:34
 */

class SwooleTcpPython
{
    CONST HOST = "0.0.0.0";
    CONST PORT = 9503;

    public $tcp = null;
    public function __construct( )
    {
        $this->tcp = new swoole_server(self::HOST, self::PORT);
    }

    /**
     * 启动程序
     */
    public function start()
    {
        $this->tcp->set(
            [
                'worker_num' => 4,
                'max_request' => 1000,
                "daemonize"   => 1,
                "open_tcp_keepalive"  => 1
            ]
        );
        $this->tcp->on('connect', [$this, 'onConnect']);
        $this->tcp->on('receive', [$this, 'onReceive']);
        $this->tcp->on('close', [$this, 'onClose']);
        swoole_set_process_name("python_call_back");
        $this->tcp->start();
    }

    /**
     * 重启进程
     */
    public function reload()
    {
        $this->tcp->reload();
    }

    /**
     * 关闭进程
     */
    public function stop()
    {
        $this->tcp->stop();
    }



    /**
     * 监听连接事件
     * @param $tcp
     * @param $fd
     * @param $reactor_id
     */
    public function onConnect($tcp, $fd, $reactorId)
    {
        echo "客户端id:{$fd}连接成功,来自于线程{$reactorId}\n";
    }

    /**
     * 监听接收事件
     * @param swoole_server $tcp
     * @param $fd
     * @param $reactorId
     * @param $data
     * @return bool
     */
    public function onReceive( swoole_server $tcp, $fd, $reactorId, $data)
    {
        try{
            $data = json_decode( $data,true );
            ElkLog::write( array( "message"=> "onReceive", "data"=> $data ) );
            if ( !is_array( $data ) ){
                $tcp->send( $fd, CommonFun::json_encode2( array( "errno" => 9001, "error" => "数据格式错误" ) ) );
                return false;
            }

            $res = $this->call_back( $data );
            if ( !$res ){
                $tcp->send( $fd, CommonFun::json_encode2( array( "errno" => 9001, "error" => "数据格式错误" ) ) );
                return false;
            }
            $sendData = CommonFun::json_encode2( array( "errno" => 0, "message" => "数据调用成功" ) );
            $tcp->send($fd, $sendData);
        }catch ( \Exception $e ){
            echo "数据处理错误".$e;
            $tcp->send( $fd, CommonFun::json_encode2( array( "errno" => 9002, "error" => "数据处理错误".$e ) ) );
        }
        return true;
    }

    /**
     * @param $data
     * @return bool
     */
    public function call_back( $data )
    {
        // 检测类和方法是否存在
        if ( class_exists( $data['module'] ) && method_exists( $data['module'], $data['method'] ) ){
            call_user_func_array( array( $data['module'], $data['method'] ), array( $data['param'] ) );
            return true;
        } else {
            ElkLog::write( array( "message"=> "onReceiveError", "data"=> $data ) );
            return false;
        }
    }

    /**
     * 监听关闭事件
     * @param $tcp
     * @param $fd
     */
    public function onClose($tcp, $fd)
    {
        echo "客户端id: {$fd} 关闭了连接\n";
    }

}